﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Windows;
//using System.Windows.Media.Animation;
//using System.Diagnostics;

//namespace InnovTech.Wpf.Media
//{
//        // TODO: Animation Support
//    // Gewusst wie: Festlegen einer Eigenschaft nach einer Storyboard-Animation (FillBehavior.Stop, ...)
//    //              http://msdn.microsoft.com/de-de/library/aa970493.aspx
//    public class StoryboardManager
//    {
//        #region Constructors

//        protected StoryboardManager() { }

//        #endregion

//        #region public static methods

//        /// <summary>
//        /// start all animations of a Storyboard on the given target FrameworkElement
//        /// </summary>
//        /// <param name="sb">the Storyboard should be started</param>
//        /// <param name="target">the target FrameworkElement on which the given Storyboard should be played</param>
//        /// <param name="isAnimationControllable">indicate whether the animations in the given Storyboard should be controlled. for example pause, resumme, start, end</param>
//        public static void BeginAnimation(Storyboard sb, FrameworkElement target, bool isAnimationControllable)
//        {
//            ResetStoryboard(sb, target);
//            sb.Begin(target, isAnimationControllable);
//        }
//        /// <summary>
//        /// start all animations of a Storyboard on the given target FrameworkElement
//        /// </summary>
//        /// <param name="sb">the Storyboard should be started</param>
//        /// <param name="target">the target FrameworkElement on which the given Storyboard should be played</param>
//        public static void BeginAnimation(Storyboard sb, FrameworkElement target)
//        {
//            BeginAnimation(sb, target, true);
//        }
//        /// <summary>
//        /// start all animations of a Storyboard on the given target FrameworkContentElement
//        /// </summary>
//        /// <param name="sb">the Storyboard should be started</param>
//        /// <param name="target">the target FrameworkContentElement on which the given Storyboard should be played</param>
//        /// <param name="isAnimationControllable">indicate whether the animations in the given Storyboard should be controlled. for example pause, resumme, start, end</param>
//        public static void BeginAnimation(Storyboard sb, FrameworkContentElement target, bool isAnimationControllable)
//        {
//            ResetStoryboard(sb, target);
//            sb.Begin(target, isAnimationControllable);
//        }
//        /// <summary>
//        /// start all animations of a Storyboard on the given target FrameworkContentElement
//        /// </summary>
//        /// <param name="sb">the Storyboard should be started</param>
//        /// <param name="target">the target FrameworkContentElement on which the given Storyboard should be played</param>
//        public static void BeginAnimation(Storyboard sb, FrameworkContentElement target)
//        {
//            BeginAnimation(sb, target, true);
//        }

//        public static Storyboard FindStoryboard(String resourceKey, FrameworkElement relativeTo)
//        {
//            object resource = relativeTo.TryFindResource(resourceKey);
//            if (resource == null)
//            {
//                Trace.WriteLine(String.Format("Can not find storyboard '{0}' for element '{1}'", resourceKey, relativeTo));
//                return null;
//            }

//            if (resource is Storyboard)
//            {
//                // Force Storyboard type
//                Storyboard sb = resource as Storyboard;

//                // Storyboard when put in a Style will get frozen so the Style can be accessed safely across thread boundaries
//                if (sb.IsFrozen)
//                {
//                    sb = sb.Clone();
//                }
//                return sb;
//            }
//            else
//            {
//                throw new InvalidCastException(String.Format("Resource '{0}' has to be a storyboard.", resourceKey));
//            }
//        }

//        #endregion public static methods

//        #region private static methods
//        /// <summary>
//        /// copy the end value of a animation to the given target UIElement
//        /// assumption: the given animation uses only the simplest and direct PropertyPath
//        /// </summary>
//        /// <param name="anim">a animation which change the value of a dependency property of the given UIElement</param>
//        /// <param name="target">a UIElement whose property should be changed after the playing of the given animation</param>
//        private static void CopyEnd(AnimationTimeline anim, IAnimatable target)
//        {
//            if (anim == null || target == null) return;
//            AnimatedTarget animTarget = GetAnimationTarget(anim, target);
//            if (!animTarget.IsValid) return;
//            IAnimatable animatable = (animTarget.Target as IAnimatable);
//            if (animatable == null)
//                return;
//            if (anim.FillBehavior == FillBehavior.HoldEnd)
//            {
//                anim.Completed += delegate(object sender, EventArgs e)
//                    {
//                        var endValue = animTarget.Target.GetValue(animTarget.Property);
//                        animTarget.Target.SetValue(animTarget.Property, endValue);
//                        //only stoped animations should be removed from the target 
//                        animatable.BeginAnimation(animTarget.Property, null);
//                    };
//            }
//        }


//        /// <summary>
//        /// copy the end values of all animations in the given Storyboard to the given target UIElement
//        /// </summary>
//        /// <param name="sb">a Storyboard which contains animations to change the values of dependency properties</param>
//        /// <param name="target"></param>
//        private static void CopyEnd(Storyboard sb, IAnimatable target)
//        {
//            foreach (Timeline tl in sb.Children)
//            {
//                if (tl is Storyboard)
//                {
//                    CopyEnd(tl as Storyboard, target);
//                }
//                if (tl is AnimationTimeline)
//                {
//                    CopyEnd(tl as AnimationTimeline, target);
//                }
//            }
//        }

//        //man can set the FillBehavior only on Storyboard. when this value between Storyboard and animations is different,
//        //then only the value of Storyboard is used
//        //example Storyboard.FillBehavior = Stop and animation.FillBehavior = HoldEnd then animation runs as FillBehavior = Stop
//        //but when Storyboard.FillBehavior = HoldEnd => animation runs as its FillBehavior
//        /// <summary>
//        /// get the by the given animation aimed target. A animatedTarget object contains the aimed DependencyObject and its DependencyProperty
//        /// </summary>
//        /// <param name="anim">a animation</param>
//        /// <param name="originTarget">the value of the attached property (Storyboard.TargetProperty)</param>
//        /// <returns>the by the given animation aimed target</returns>
//        private static AnimatedTarget GetAnimatedTarget(AnimationTimeline anim, DependencyObject originTarget)
//        {
//            AnimatedTarget result = new AnimatedTarget();
//            if (originTarget == null)
//                return result;
//            PropertyPath propPath = GetPropertyPath(anim);
//            if (propPath == null)
//                return result;
//            PropertyPathUtil.GetAnimatedTarget(originTarget, propPath, ref result);
//            return result;
//        }

//        /// <summary>
//        ///  get the by the given animation aimed target. That animation must be managed by a Storyboard. A animatedTarget object contains the aimed DependencyObject and its DependencyProperty
//        /// </summary>
//        /// <param name="anim">a animation</param>
//        /// <param name="animatedOriginContainer">the container object (FrameworkElement or FrameworkContentElement) which contains the animated target</param>
//        /// <returns>the by the given animation aimed target</returns>
//        private static AnimatedTarget GetAnimationTarget(AnimationTimeline anim, IAnimatable animatedOriginContainer)
//        {

//            if (animatedOriginContainer == null) return new AnimatedTarget();
//            DependencyObject animationTarget = null;

//            //only FrameworkElement and FrameworkContentElement surpport the FindName method and be surpoported by Storyboard
//            if (animatedOriginContainer is FrameworkElement || animatedOriginContainer is FrameworkContentElement)
//                animationTarget = animatedOriginContainer as DependencyObject;

//            string targetName = anim.GetValue(Storyboard.TargetNameProperty) as string;
//            if (!string.IsNullOrEmpty(targetName))
//            {
//                if (animationTarget is FrameworkElement)
//                    animationTarget = (animationTarget as FrameworkElement).FindName(targetName) as DependencyObject;
//                if (animationTarget is FrameworkContentElement)
//                    animationTarget = (animationTarget as FrameworkContentElement).FindName(targetName) as DependencyObject;
//            }
//            return GetAnimatedTarget(anim, animationTarget);
//        }

//        /// <summary>
//        /// get the PropertyPath of the given animation
//        /// </summary>
//        /// <param name="anim">a animation</param>
//        /// <returns>the PropertyPath (Storyboard.TargetPropertyProperty) which be attached on the given animation</returns>
//        private static PropertyPath GetPropertyPath(AnimationTimeline anim)
//        {
//            return anim.GetValue(Storyboard.TargetPropertyProperty) as PropertyPath;
//        }

//        private static void ResetStoryboard(Storyboard sb, IAnimatable target)
//        {
//            if (GetCopyEnd(sb))
//            {
//                CopyEnd(sb, target);
//            }
            
//        }

//        #endregion private static methods

//        #region CopyEnd

//        #region Fields

//        public static DependencyProperty CopyEndProperty =
//            DependencyProperty.RegisterAttached("CopyEnd", typeof(bool), typeof(StoryboardManager),
//                                                new PropertyMetadata(false, new PropertyChangedCallback(CopyEndPropertyOnChanged)));

//        #endregion

//        #region Methods

//        [AttachedPropertyBrowsableForType(typeof(Storyboard))]
//        public static bool GetCopyEnd(Storyboard sb)
//        {
//            return (bool)sb.GetValue(StoryboardManager.CopyEndProperty);
//        }

//        [AttachedPropertyBrowsableForType(typeof(Storyboard))]
//        public static void SetCopyEnd(Storyboard sb, bool copyEnd)
//        {
//            sb.SetValue(StoryboardManager.CopyEndProperty, copyEnd);
//        }

//        protected static void CopyEndPropertyOnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
//        {
//            Storyboard sb = sender as Storyboard;
//            if ((bool)e.NewValue)
//            {
//                sb.FillBehavior = FillBehavior.HoldEnd;
//            }
//        }

//        #endregion

//        #endregion CopyEnd
//    }
//}
